package com.tyk.bookstore.front.comment.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tyk.bookstore.front.comment.model.entity.CommentDo;
import com.tyk.bookstore.front.comment.model.entity.ReplyDo;
import com.tyk.bookstore.front.comment.model.query.ReplyAddQuery;
import com.tyk.bookstore.front.comment.model.query.ReplyPageQuery;
import com.tyk.bookstore.front.comment.model.result.CommentResultEnum;
import com.tyk.bookstore.front.comment.model.result.ReplyResultEnum;
import com.tyk.bookstore.front.comment.model.vo.ReplyPageVo;
import com.tyk.bookstore.front.comment.repository.CommentRepository;
import com.tyk.bookstore.front.comment.repository.ReplyRepository;
import com.tyk.bookstore.front.comment.service.ReplyService;
import com.tyk.bookstore.front.comment.util.MapStructComment;
import com.tyk.bookstore.front.common.core.model.vo.PageVo;
import com.tyk.bookstore.front.common.core.util.AssertUtil;
import com.tyk.bookstore.front.common.core.util.IdGenerator;
import com.tyk.bookstore.front.member.model.dto.Member4CommentDto;
import com.tyk.bookstore.front.member.service.MemberApiService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.support.TransactionTemplate;

import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author tyk
 * @description 回复管理
 */
@Service
@RequiredArgsConstructor
public class ReplyServiceImp implements ReplyService {
    private final CommentRepository commentRepository;
    private final ReplyRepository replyRepository;
    private final MemberApiService memberApiService;
    private final TransactionTemplate transactionTemplate;
    private final MapStructComment mapStructComment;
    private final IdGenerator idGenerator;

    @Override
    public void add(ReplyAddQuery query) {

        long memberId = StpUtil.getLoginIdAsLong();

        transactionTemplate.executeWithoutResult(status -> {

            // 评论存在
            AssertUtil.isTrue(
                    commentRepository.exist1Eq(
                            CommentDo::getId, query.getCommentId(),
                            CommentDo.class
                    ),
                    CommentResultEnum.COMMENT_NOT_FOUND
            );

            // 父级存在
            AssertUtil.isTrue(
                    query.getParentId() == 0 || replyRepository.exist1Eq(
                            ReplyDo::getId, query.getParentId(), ReplyDo.class
                    ),
                    ReplyResultEnum.REPLY_NOT_FOUND
            );

            // 回复
            ReplyDo reply = mapStructComment.toReplyDo(query).setMemberId(memberId).setId(IdGenerator.id());
            replyRepository.insert(reply);

        });
    }

    @Override
    public ReplyPageVo getPage(ReplyPageQuery query) {

        // 回复
        Page<ReplyDo> page = new Page<>(query.getPage(), query.getLimit());
        LambdaQueryWrapper<ReplyDo> w = Wrappers.lambdaQuery(ReplyDo.class);
        w.eq(query.getCommentId() != null, ReplyDo::getCommentId, query.getCommentId());
        w.orderByAsc(ReplyDo::getCreateTime);
        replyRepository.selectPage(page, w);

        // 特判
        if (page.getTotal() == 0L) return PageVo.instance(ReplyPageVo.class);
        ReplyPageVo rpv = mapStructComment.toReplyPageVo(page);

        // 会员ID
        Set<Long> midSet = new HashSet<>();
        page.getRecords().forEach(it -> {
            midSet.add(it.getMemberId());
            midSet.add(it.getAtMemberId());
        });


        // 会员名称
        Map<Long, Member4CommentDto> mnMap = memberApiService
                .getMember4CommentDtoListByIdSet(midSet)
                .stream().collect(Collectors.toMap(
                        Member4CommentDto::getMemberId, it -> it
                ));

        // 补充会员名称
        rpv.getRecords().forEach(it -> {
            Member4CommentDto dto = mnMap.get(it.getMemberId());
            it.setMemberName(dto.getNickname()).setMemberAvatar(dto.getAvatar());
//            if (!ObjUtil.equal(it.getParentId(), ReplyDo.TOP_ID)) {
//                dto = mnMap.get(it.getAtMemberId());
//                it.setAtMemberName(dto.getNickname());
//            }
            dto = mnMap.get(it.getAtMemberId());
            it.setAtMemberName(dto.getNickname());
        });

        return rpv;
    }

    @Override
    public void deleteById(Long id) {
        long memberId = StpUtil.getLoginIdAsLong();
        // 回复存在
        AssertUtil.isTrue(
                replyRepository.exist2Eq(
                        ReplyDo::getId, id,
                        ReplyDo::getMemberId, memberId,
                        ReplyDo.class
                ),
                ReplyResultEnum.REPLY_NOT_FOUND
        );
        // 删除回复
        replyRepository.deleteById(id);
    }
}
